﻿/* $RCSFile: CrmRatingUtil.cs $
 * Apache license v2 2011 by Christian Surieux
 * $Source: ?/AddonNice/PageModules/CrmRating/CrmRatingUtil.cs $
 * $log$
 * Revision 19 2010/08/09 09:43:51  christian.surieux
 *   Added Log to cs sources files
 * Revision 6 2010/08/06 19:56:25  christian.surieux
 *   Added Log to All cs files
 */

using System;
using System.Diagnostics;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Web.Services.Protocols;
using System.Globalization;

using AddonNice.UI;
using AddonNice.UI.WebControls;
using AddonNice.UI.DataTypes;
using AddonNice.Configuration;
using AddonNice.Settings;
using AddonNice.Diagnostics;
using AddonNice.Helpers;
using AddonNice.Configuration.Settings;
using AddonNice.Settings.PageModules.CrmRating;
using AddonNice.CRMWrapper;
using AddonNice.Authentication;
using AddonNice.CRMWrapper.CrmRating;

using Telerik.Web.UI;

using Trace2    =   System.Diagnostics.Trace;

namespace AddonNice.PageModules.CrmRating
{
 	#region Local TraceSwitch 
	public class RatingTrace : ADNTraceSwitch
	{
		static public ADNTraceSwitch	Sw	=	new ADNTraceSwitch("RatingTrace","Special Trace Switch for Ratings");
	}
	#endregion Local TraceSwitch 

    public class RStr
    {
        public const string NumberStars         =   "CRMRATING_NUMBERSTAR";
        public const string SelectionMode       =   "CRMRATING_SELECTIONMODE";
        public const string IsDirectionReversed =   "CRMRATING_ISDIRECTIONREVERSED";
        public const string Precision           =   "CRMRATING_PRECISION";
        public const string Orientation         =   "CRMRATING_ORIENTATION";
        public const string Owner               =   "CRMRATING_OWNER";
        public const string AssignToOwner       =   "CRMRATING_OWNER_AUTOASSIGN";
        public const string UseCrm              =   "CRMRATING_USECRM";
        public const string UseFullInfo         =   "CRMRATING_USEFULLINFO";
        public const string ShowTitleCol        =   "CRMRATING_SHOWTITLECOL";
        public const string ShowDescCol         =   "CRMRATING_SHOWDESCCOL";
        public const string Campaign            =   "CRMRATING_CAMPAIGN";
        public const string GenerateLead        =   "CRMRATING_GENERATELEAD";
        public const string CampaignAnswer      =   "CRMRATING_GENERATECAMPAIGNANSWER";
        public const string AllowAnonymous      =   "CRMRATING_ALLOWANONYMOUS";
        public const string InputComment        =   "CRMRATING_INPUTCOMMENT";
    }

    /// <summary>
    /// Initializer for CrmRating 
    /// </summary>
    public class CrmRatingBaseSI : PortalCRMModuleControlSI
    {
        public CrmRatingBaseSI() : base()
        {}

        public CrmRatingBaseSI(ModuleSettingsDictionary bSettings,ISettingsOwner pm) : base()
        {
            if ( RatingTrace.Sw.TraceVerbose )
                Trace2.WriteLine("[V]RatingContextBaseSI Ctor BEG.",RatingTrace.Sw.Info);
            InitSettings(bSettings,pm);
            if ( RatingTrace.Sw.TraceVerbose )
                Trace2.WriteLine( "[V]RatingContextBaseSI Ctor END.",RatingTrace.Sw.Info);
        }

        public override void InitSettings(ModuleSettingsDictionary bSettings,ISettingsOwner pm)
        {             
            if ( RatingTrace.Sw.TraceVerbose )
                Trace2.WriteLine( "[V]RatingContextBaseSI InitSettings BEG.",RatingTrace.Sw.Info);
            base.InitSettings(bSettings,pm);

            const string extgrp                     =   "CRMRATING";

            // Test for rating entity in target Crm
            bool ExistRating                        =   Wrapper.ExistEntityMetadata(CrmStr.rating);
            
			// Set Editor Settings 
			HtmlEditorDataType.AddEditorToSettings(bSettings, SettingItemGroup.MODULE_SPECIAL_SETTINGS,extgrp);

            IntegerDataType idt                     =   new IntegerDataType();
            idt.DecimalDigits                       =   0;
			SettingItemSpecial NumberStars	        =	new SettingItemSpecial(RStr.NumberStars,idt);
			NumberStars.Value		                =	"5";        
            NumberStars.MinValue                    =   1;
            NumberStars.MaxValue                    =   10;
			NumberStars.Order		                =	10;	
			NumberStars.ExtendedGroupName           =   extgrp;
            NumberStars.Description		            =	"Number of Stars.";
			NumberStars.EnglishName		            =	"Star Number";
			bSettings.AddSetting(NumberStars);

            SettingItemSpecial SelectionMode        =   new SettingItemSpecial(RStr.SelectionMode,new ListDataType(typeof(RatingSelectionMode)));
			SelectionMode.Order			            =	20;
			SelectionMode.Value		                =	RatingSelectionMode.Continuous.ToString();        
            SelectionMode.ExtendedGroupName         =   extgrp;
            SelectionMode.Group                     =   SettingItemGroup.MODULE_SPECIAL_SETTINGS;
			SelectionMode.Description		        =	"Selection Mode";
            SelectionMode.EnglishName		        =	"Selection Mode";
			bSettings.AddSetting(SelectionMode);
            
            SettingItemSpecial IsDirectionReversed  =   new SettingItemSpecial(RStr.IsDirectionReversed,new BooleanDataType());
			IsDirectionReversed.Order			    =	30;
            IsDirectionReversed.ExtendedGroupName   =   extgrp;
            IsDirectionReversed.Group               =   SettingItemGroup.MODULE_SPECIAL_SETTINGS;
            IsDirectionReversed.Value			    =	StStr.strFalse; // default value
			IsDirectionReversed.Description		    =	"Is Direction Reversed";
            IsDirectionReversed.EnglishName		    =	"Is Direction Reversed";
			bSettings.AddSetting(IsDirectionReversed);

            SettingItemSpecial Precision            =   new SettingItemSpecial(RStr.Precision,new ListDataType(typeof(RatingPrecision)));
			Precision.Order			                =	40;
			Precision.Value		                    =	RatingPrecision.Item.ToString();        
            Precision.ExtendedGroupName             =   extgrp;
            Precision.Group                         =   SettingItemGroup.MODULE_SPECIAL_SETTINGS;
			Precision.Description		            =	"Precision";
            Precision.EnglishName		            =	"Precision";
			bSettings.AddSetting(Precision);
            
            SettingItemSpecial SOrientation         =   new SettingItemSpecial(RStr.Orientation,new ListDataType(typeof(Orientation)));
			SOrientation.Order			            =	50;
			SOrientation.Value		                =	Orientation.Horizontal.ToString();        
            SOrientation.ExtendedGroupName          =   extgrp;
            SOrientation.Group                      =   SettingItemGroup.MODULE_SPECIAL_SETTINGS;
			SOrientation.Description		        =	"Orientation";
            SOrientation.EnglishName		        =	"Orientation";
			bSettings.AddSetting(SOrientation);
            
            SettingItemSpecial UseFullInfo          =   new SettingItemSpecial(RStr.UseFullInfo,new BooleanDataType());
            UseFullInfo.Required                    =   false;
            UseFullInfo.Value                       =   StStr.strFalse;
            UseFullInfo.Order                       =   54;
            UseFullInfo.ExtendedGroupName           =   extgrp;
            UseFullInfo.EnglishName                 =   "Use full info";
            UseFullInfo.Description                 =   "Check to input full user info when rating";
            bSettings.AddSetting(UseFullInfo);

            SettingItemSpecial ShowTitleCol          =   new SettingItemSpecial(RStr.ShowTitleCol,new BooleanDataType());
            ShowTitleCol.Required                    =   false;
            ShowTitleCol.Value                       =   StStr.strTrue;
            ShowTitleCol.Order                       =   56;
            ShowTitleCol.ExtendedGroupName           =   extgrp;
            ShowTitleCol.EnglishName                 =   "Show Title";
            ShowTitleCol.Description                 =   "Hide or show Title column";
            bSettings.AddSetting(ShowTitleCol);

            SettingItemSpecial ShowDescCol          =   new SettingItemSpecial(RStr.ShowDescCol,new BooleanDataType());
            ShowDescCol.Required                    =   false;
            ShowDescCol.Value                       =   StStr.strFalse;
            ShowDescCol.Order                       =   58;
            ShowDescCol.ExtendedGroupName           =   extgrp;
            ShowDescCol.EnglishName                 =   "Show Description";
            ShowDescCol.Description                 =   "Hide or show Description column";
            bSettings.AddSetting(ShowDescCol);

            SettingItemSpecial UseCrm               =   new SettingItemSpecial(RStr.UseCrm,new BooleanDataType());
            UseCrm.Required                         =   false;
            UseCrm.Value                            =   StStr.strTrue;
            UseCrm.Order                            =   60;
            UseCrm.ExtendedGroupName                =   extgrp;
            UseCrm.EnglishName                      =   "Use Crm";
            UseCrm.Description                      =   "When checked the rating will be managed by CRM rating entity";
            bSettings.AddSetting(UseCrm);

            SettingItemSpecial AllowAnonymous       =   new SettingItemSpecial(RStr.AllowAnonymous,new BooleanDataType());
            AllowAnonymous.Required                 =   false;
            AllowAnonymous.Value                    =   StStr.strTrue;
            AllowAnonymous.Order                    =   65;
            AllowAnonymous.ExtendedGroupName        =   extgrp;
            AllowAnonymous.EnglishName              =   "Allow Anonymous";
            AllowAnonymous.Description              =   "When checked allow anonymous users to rate";
            bSettings.AddSetting(AllowAnonymous);

            SettingItemSpecial InputComment         =   new SettingItemSpecial(RStr.InputComment,new BooleanDataType());
            InputComment.Required                   =   false;
            InputComment.Value                      =   StStr.strTrue;
            InputComment.Order                      =   68;
            InputComment.ExtendedGroupName          =   extgrp;
            InputComment.EnglishName                =   "Input Comments";
            InputComment.Description                =   "When checked allow users to input a comment when rating";
            bSettings.AddSetting(InputComment);

            SettingItemSpecial AttributeOwner       =   new SettingItemSpecial(RStr.AssignToOwner,new BooleanDataType());
            AttributeOwner.Required                 =   false;
            AttributeOwner.Value                    =   StStr.strFalse;
            AttributeOwner.Order                    =   70;
            AttributeOwner.ExtendedGroupName        =   extgrp;
            AttributeOwner.EnglishName              =   "Assign to Owner";
            AttributeOwner.Description              =   "When checked, the new ratings will be automatically assigned to selected owner";
            bSettings.AddSetting(AttributeOwner);

            WSListDataType defAcc                   =   new WSListDataType(CrmStr.systemuser,"name", "ID");
            SettingItemSpecial ModuleOwner          =   new SettingItemSpecial(RStr.Owner,defAcc);
            ADNDynSystemUser wsys                   =   null;
            if (!string.IsNullOrEmpty(Config.CRMDefaultAccount))
            {
                string domainName                   =   string.Format("{0}\\{1}",Config.CRMDefaultAccountDomain,Config.CRMDefaultAccount);
                wsys                                =   Wrapper.Util.FindSystemUserByDomainName(domainName);
            }
            else 
            {
                wsys                                =   DynEntity.GetFromCache<ADNDynSystemUser>(CrmStr.systemuser,Wrapper,new ResetWrapperHandler(ResetWrapper),Wrapper.adminUserId);
            }
            if (wsys != null)
            {
                ModuleOwner.Value                   =   wsys.systemuserid.ToString();
                defAcc.DisplayTextValue             =   wsys.fullname;
            }
            ModuleOwner.EnglishName                 =   "Owner";
            ModuleOwner.Order                       =   80;
            ModuleOwner.ExtendedGroupName           =   extgrp;
            ModuleOwner.Description                 =   "Choose the owner for orders created with this module if previous checkbox checked";
            ModuleOwner.SettingItemsEvent           +=  new SettingItemsEventHandler(ModuleOwner_SettingItemsEvent);
            bSettings.AddSetting(ModuleOwner);

            WSListDataType defCampaign              =   new WSListDataType(CrmStr.campaign,"name", "ID");
            SettingItemSpecial Campaign             =   new SettingItemSpecial(RStr.Campaign,defCampaign);
            Campaign.EnglishName                    =   "Campaign";
            Campaign.Order                          =   90;
            Campaign.ExtendedGroupName              =   extgrp;
            Campaign.Description                    =   "Select a default compaign to associate with this Rating";
            Campaign.SettingItemsEvent              +=  new SettingItemsEventHandler(Campaign_SettingItemsEvent);
            bSettings.AddSetting(Campaign);

            SettingItemSpecial GenerateLead          =   new SettingItemSpecial(RStr.GenerateLead,new BooleanDataType());
            GenerateLead.Required                    =   false;
            GenerateLead.Value                       =   StStr.strTrue;
            GenerateLead.Order                       =   110;
            GenerateLead.ExtendedGroupName           =   extgrp;
            GenerateLead.EnglishName                 =   "Generate Lead";
            GenerateLead.Description                 =   "Automatically generates a lead on answer if anonymous user";
            bSettings.AddSetting(GenerateLead);

            SettingItemSpecial CampaignAnswer        =   new SettingItemSpecial(RStr.CampaignAnswer,new BooleanDataType());
            CampaignAnswer.Required                  =   false;
            CampaignAnswer.Value                     =   StStr.strTrue;
            CampaignAnswer.Order                     =   120;
            CampaignAnswer.ExtendedGroupName         =   extgrp;
            CampaignAnswer.EnglishName               =   "Generate Campaign answer";
            CampaignAnswer.Description               =   "Automatically generates a campaign answer";
            bSettings.AddSetting(CampaignAnswer);

            if ( RatingTrace.Sw.TraceVerbose )
                Trace2.WriteLine("[V]RatingContextBaseSI Ctor END.",RatingTrace.Sw.Info);
        }

        /// <summary>
        /// Used to set the good display value in ModuleOwner when loaded from DB
        /// </summary>
        void ModuleOwner_SettingItemsEvent(object sender, SettingItemsEventArgs e)
        {
            if ( e.EventType != SettingItemsEventType.Loaded )
                return;
            if ( RatingTrace.Sw.TraceVerbose )
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]RatingContextBaseSI ModuleOwner_SettingItemsEvent Guid: {0}", e.Data),RatingTrace.Sw.Info);
            Guid custId                 =   new Guid((string)e.Data);
            if ( custId == Guid.Empty )
                return;
            ADNDynSystemUser dynac      =   DynEntity.GetFromCache<ADNDynSystemUser>(CrmStr.systemuser,Wrapper,new ResetWrapperHandler(ResetWrapper),custId);
            WSListDataType defAcc       =   (WSListDataType )((SettingItem)sender).DataType;
            defAcc.DisplayTextValue     =   dynac.fullname;
            if ( RatingTrace.Sw.TraceVerbose )
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]RatingContextBaseSI ModuleOwner_SettingItemsEvent END name: {0}", dynac.name),RatingTrace.Sw.Info);
        }
        
        /// <summary>
        /// Used to set the good display value in Campaign when loaded from DB
        /// </summary>
        void Campaign_SettingItemsEvent(object sender, SettingItemsEventArgs e)
        {
            if ( e.EventType != SettingItemsEventType.Loaded )
                return;
            if ( RatingTrace.Sw.TraceVerbose )
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]RatingContextBaseSI Campaign_SettingItemsEvent Guid: {0}", e.Data),RatingTrace.Sw.Info);
            Guid custId                     =   new Guid((string)e.Data);
            if ( custId == Guid.Empty )
                return;
            ADNDynCampaign dynac            =   DynEntity.GetFromCache<ADNDynCampaign>(CrmStr.campaign,Wrapper,new ResetWrapperHandler(ResetWrapper),custId);
            WSListDataType defCampaign      =   (WSListDataType )((SettingItem)sender).DataType;
            defCampaign.DisplayTextValue    =   dynac.name;
            if ( RatingTrace.Sw.TraceVerbose )
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]RatingContextBaseSI ModuleOwner_SettingItemsEvent END name: {0}", dynac.name),RatingTrace.Sw.Info);
        }
    }

    public class RatingContext : IStateManager
    {
		RatingDB CrmRatingDB                =   new RatingDB();
        ModuleSettingsDictionary Settings   =   null;
        CRMWrapperBase Wrapper              =   null;
        ResetWrapperHandler ResetWrapper    =   null;
        HttpRequest Request                 =   null;

        #region  IStateManager

        bool _IsTrackingViewState           =   false;
        StateBag _ViewState                 =   null;
        [Browsable(false),DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]


        protected StateBag ViewState                  
        {
            get
            {
                if (_ViewState == null )
                {
                    _ViewState  =   new StateBag(false);
                    if ( _IsTrackingViewState )
                    {
                        ((IStateManager)_ViewState).TrackViewState();
                    }
                }
                return _ViewState;
            }
        }

        internal void SetDirty()
        {
            if ( _ViewState != null )
            {
                ICollection Keys    =   _ViewState.Keys;
                foreach ( string key in Keys )
                    _ViewState.SetItemDirty(key,true);
            }
        }

        bool IStateManager.IsTrackingViewState
        {
            get { return _IsTrackingViewState; }
        }

        void IStateManager.LoadViewState(object SavedState)
        {
            if ( SavedState != null )
            {
                ( (IStateManager)ViewState ).LoadViewState(SavedState);
            }
        }

        object IStateManager.SaveViewState()
        {
            if ( _ViewState != null )
                return ( (IStateManager)_ViewState ).SaveViewState();
            return null;
        }

        void IStateManager.TrackViewState()
        {
            _IsTrackingViewState    =   true;
            if (_ViewState != null )
                ( (IStateManager)_ViewState ).TrackViewState();
        }
        #endregion  IStateManager

        public bool RatingExist
        {
            get
            {
                object ob   =   ViewState["RatingExist"];
                if ( ob == null )
                    return false;
                return (bool)ob;
            }
            set
            {
                ViewState["RatingExist"]    =   value;
            }
        }

        public int StarNumber
        {
            get
            {
                object ob   =   ViewState["StarNumber"];
                if ( ob == null )
                    return Settings[RStr.NumberStars].ToInt();
                return (int)ob;
            }
            set
            {
                ViewState["StarNumber"]    =   value;
            }
        }

        public int ItemCount
        {
            get
            {
                object ob   =   ViewState["ItemCount"];
                if ( ob == null )
                    return 0;
                return (int)ob;
            }
            set
            {
                ViewState["ItemCount"]    =   value;
            }
        }

        public int RatingItemID            
        {
            get
            {
                object ob   =   ViewState["RatingItemID"];
                if ( ob == null )
                    return 0;
                return (int)ob;
            }
            set
            {
                ViewState["RatingItemID"]    =   value;
            }
        }

        public Guid RatingCrmDetailID
        {
            get
            {
                object ob   =   ViewState["RatingCrmDetailID"];
                if ( ob == null )
                    return Guid.Empty;
                return (Guid)ob;
            }
            set
            {
                ViewState["RatingCrmDetailID"]    =   value;
            }
        }

        public Guid RatingCrmEntityID
        {
            get
            {
                object ob   =   ViewState["RatingCrmEntityID"];
                if ( ob == null )
                    return Guid.Empty;
                return (Guid)ob;
            }
            set
            {
                ViewState["RatingCrmEntityID"]    =   value;
            }
        }
    
        public Guid RatingAnswerCrmID
        {
            get
            {
                object ob   =   ViewState["RatingAnswerCrmID"];
                if ( ob == null )
                    return Guid.Empty;
                return (Guid)ob;
            }
            set
            {
                ViewState["RatingAnswerCrmID"]    =   value;
            }
        }

        public double AverageRating
        {
            get
            {
                object ob   =   ViewState["AverageRating"];
                if ( ob == null )
                    return 0;
                return (double)ob;
            }
            set
            {
                ViewState["AverageRating"]    =   value;
            }
        }

        public int TimesRated
        {
            get
            {
                object ob   =   ViewState["TimesRated"];
                if ( ob == null )
                    return 0;
                return (int)ob;
            }
            set
            {
                ViewState["TimesRated"]    =   value;
            }
        }

        public decimal RatedAverageValue
        {
            get
            {
                object ob   =   ViewState["RatedAverageValue"];
                if ( ob == null )
                    return 0;
                return (decimal)ob;
            }
            set
            {
                ViewState["RatedAverageValue"]    =   value;
            }
        }


        public int RatingAnswerID            
        {
            get
            {
                object ob   =   ViewState["RatingAnswerID"];
                if ( ob == null )
                    return 0;
                return (int)ob;
            }
            set
            {
                ViewState["RatingAnswerID"]    =   value;
            }
        }

        public string RatingEntityName
        {
            get
            {
                object ob   =   ViewState["RatingEntityName"];
                if ( ob == null )
                    return string.Empty;
                return (string)ob;
            }
            set
            {
                ViewState["RatingEntityName"]    =   value;
            }
        }
					
        public string TitleRating
        {
            get
            {
                object ob   =   ViewState["TitleRating"];
                if ( ob == null )
                    return string.Empty;
                return (string)ob;
            }
            set
            {
                ViewState["TitleRating"]    =   value;
            }
        }

        public string TitleRatingDetail
        {
            get
            {
                object ob   =   ViewState["TitleRatingDetail"];
                if ( ob == null )
                    return string.Empty;
                return (string)ob;
            }
            set
            {
                ViewState["TitleRatingDetail"]    =   value;
            }
        }

	    public bool IsCutomInstalled
        {
            get
            {
                object ob               =   ViewState["IsCutomInstalled"];
                if ( ob == null )
                {
                    DBCrmEntity entObj  =   new CrmDB().GetCrmEntityBySchemaNameObj(CrmStr.rating,new ADNDynRating().ADNDynVersion.ToString());
                    ViewState["IsCutomInstalled"] = ( entObj != null );
                    return true;
                }
                return (bool)ob;
            }
        }

        public bool ShowDescCol
        {
            get
            {
                return Settings[RStr.ShowDescCol].ToBool();
            }
        }

        public bool IsGridRating
        {
            get
            {
                object ob   =   ViewState["IsGridRating"];
                if ( ob == null )
                    return false;
                return (bool)ob;
            }
            set
            {
                ViewState["IsGridRating"]    =   value;
            }
        }

        public bool InputComment
        {
            get
            {
                return !IsGridRating && Settings[RStr.InputComment].ToBool();
            }
        }

        public bool AssignToOwner
        {
            get
            {
                if ( Settings[RStr.AssignToOwner].ToBool() )
                    return Settings[RStr.Owner].ToGuid() != Guid.Empty;
                return false;
            }
        }
        public bool UseCrm
        {
            get
            {
                return Settings[RStr.UseCrm].ToBool();
            }
        }

        private AddonNiceUser _CurrentUser = null;
        public AddonNiceUser CurrentUser
        {
            get
            {
                if (_CurrentUser == null)
                {
                    if ( RatingTrace.Sw.TraceVerbose )
                        Trace2.WriteLine("[V]RatingContext CurrentUser GET BEG.",RatingTrace.Sw.Info);
                    try
                    {
                        _CurrentUser    =   new AddonNiceUser();
                    }
                    catch (Exception ex)
                    {
                        if ( RatingTrace.Sw.TraceError )
                            Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[E]RatingContext CurrentUser GET ex: {0}", ex),RatingTrace.Sw.Info);
                        throw;
                    }
                    if ( RatingTrace.Sw.TraceVerbose )
                        Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]RatingContext CurrentUser Get Key: [{0}],userName: [{1}]",
                             _CurrentUser.ProviderUserKey, _CurrentUser.UserName),RatingTrace.Sw.Info);
                }
                if (_CurrentUser == null)
                {
                    const string msg    =   "[E]RatingContext CurrentUser is NULL";
                    if ( RatingTrace.Sw.TraceError )
                        Trace2.WriteLine(msg,RatingTrace.Sw.Info);
                    throw new Exception(msg);
                }
                return _CurrentUser;
            }
        }
       
        DynEntity _dynCurUser   =   null;
        DynEntity dynCurUser
        {
            get
            {
                if ( _dynCurUser == null )
                    _dynCurUser =   CurrentUser.CrmCustomer.GetDynUser(Wrapper,ResetWrapper);
                return _dynCurUser;
            }
        }

        public RatingContext(HttpRequest Req,CRMWrapperBase Wrap,ModuleSettingsDictionary ModuleSettings,ResetWrapperHandler fn)
        { 
            if ( RatingTrace.Sw.TraceVerbose )
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]RatingContext Ctor ModuleSettings.Count: [{0}].",
                     ModuleSettings.Count),RatingTrace.Sw.Info);
            Settings    =   ModuleSettings;
            Request     =   Req;
            Wrapper     =   Wrap;
            ResetWrapper=   fn;
            if ( RatingTrace.Sw.TraceVerbose )
                Trace2.WriteLine("[V]RatingContext Ctor END.",RatingTrace.Sw.Info);
        }
        
        public void CompleteRating(RadRating RadRating1,string UserName,Guid UserId,string EMail,string Phone,string Address,string City,string Zip,string Country,string Comments,bool UserLogged)
        {
			if (RatingTrace.Sw.TraceVerbose)
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]RatingContext CompleteRating BEG RatingAnswerID: {0}.",RatingAnswerID),RatingTrace.Sw.Info);
            string IPAddress            =   Request.UserHostAddress;
			try
			{

                CrmRatingDB.UpdateRatingAnswer(RatingAnswerID,RatingItemID,RadRating1.Value,IPAddress,UserName,UserId,EMail,Phone,Address,City,Zip,Country,Comments);
                Guid CampaignId             =   Settings[RStr.Campaign].ToGuid();
                string subject              =   string.Format("{0}: {1}",TitleRating,TitleRatingDetail);

			    if (RatingTrace.Sw.TraceVerbose)
                    Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]RatingContext CompleteRating CampaignId: {0}.",CampaignId),RatingTrace.Sw.Info);
                ADNDynLead  DynL                        =   null;
                if ( Settings[RStr.GenerateLead].ToBool() )
                {
                    if ( !UserLogged )
                    {
                        DynL                            =   new ADNDynLead(Wrapper,UserName);
                        DynL.subject                    =   string.Format("{0}: {1}",TitleRating,TitleRatingDetail);
                        DynL.leadsourcecode             =   8; // Web TBD replace with Setting selected
                        DynL.leadqualitycode            =   ( RadRating1.Value > StarNumber / 2 ) ? 1 : 3; // Hot/Cold TBD replace with Setting selected
                        DynL.emailaddress1              =   EMail;
                        DynL.telephone1                 =   Phone;
                        DynL.address1_line1             =   Address;
                        DynL.address1_city              =   City;
                        DynL.address1_postalcode        =   Zip;
                        DynL.address1_country           =   Country;
                        DynL.description                =   subject;
                        if ( CampaignId != Guid.Empty )
                            DynL.campaignid             =   CampaignId;
                        if ( AssignToOwner )
                        {
                            Guid ownerid                =   Settings[RStr.Owner].ToGuid();
			                if (RatingTrace.Sw.TraceVerbose)
                                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]RatingContext CompleteRating ownerid from settings: {0}.",ownerid),RatingTrace.Sw.Info);
                            DynL.ownerid                =   ownerid;
                        }
                        else if ( ( dynCurUser != null ) && ( dynCurUser is ADNDynSystemUser ) )
                        {
                            Guid ownerid                =   ((ADNDynSystemUser)dynCurUser).systemuserid;
			                if (RatingTrace.Sw.TraceVerbose)
                                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]RatingContext CompleteRating ownerid from dynCurUser: {0}.",ownerid),RatingTrace.Sw.Info);
                            DynL.ownerid                =   ownerid;
                        }                        
                        DynL.adminCreate();
                        if (RatingTrace.Sw.TraceVerbose)
                            Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]RatingContext CompleteRating lead created leadid: {0}.",DynL.leadid),RatingTrace.Sw.Info);
                    }
                }

                ADNDynCampaignResponse DynC             =   null;
                bool GenerateAnswer                     =   Settings[RStr.CampaignAnswer].ToBool();
                if (RatingTrace.Sw.TraceVerbose)
                    Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]RatingContext CompleteRating GenerateAnswer: {0}.",GenerateAnswer),RatingTrace.Sw.Info);
                if ( GenerateAnswer && ( CampaignId != Guid.Empty ) )
                {
                    DynC                                =   new ADNDynCampaignResponse(ResetWrapper,subject);
                    DynC.responsecode                   =   (RadRating1.Value > StarNumber/2 ) ? 1:3; // Interested/Do Not Send, TBD replace with Setting selected
                    //DynC.channeltypecode                =   7; // Email  TBD replace with Setting
                    DynC.category                       =   TitleRating;
                    DynC.subcategory                    =   TitleRatingDetail;
                    if ( DynL != null )
                    {
                        DynC.AddCustomer(DynL);
                    }
                    else if ( ( dynCurUser != null ) && !( dynCurUser is ADNDynSystemUser ) ) // we have a real user through membership, assign it as customer to the answer
                    {
                        if (RatingTrace.Sw.TraceVerbose)
                            Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]RatingContext CompleteRating Add Customer from dynCurUser SchemaName: {0}.",dynCurUser.SchemaName),RatingTrace.Sw.Info);
                        DynC.AddCustomer(dynCurUser);
                    }
                    else
                    {
                        DynC.lastname                   =   UserName;
                        DynC.emailaddress               =   EMail;
                        DynC.telephone                  =   Phone;
                    }
                    DynC.description                    =   string.Format("IP:{0},Address: {1}, City: {2}, Zip: {3}, Country: {4}, Comment: {5}",
                                                            new object[] { IPAddress,Address,City,Zip,Country,Comments });
                    DynC.DefaultRegardingObjectName     =   CrmStr.campaign; // stay before assigning regardingobjectid
                    DynC.regardingobjectid              =   CampaignId;
                    // if we must force assign to owner, do it
                    // else if current user is a systemuser, assign to him (in windows authentication, answer will be own by connected user)
                    if ( AssignToOwner )
                    {
                        Guid ownerid                    =   Settings[RStr.Owner].ToGuid();
                        DynC.ownerid                    =   ownerid;
                    }
                    else if ( ( dynCurUser != null ) && ( dynCurUser is ADNDynSystemUser ) )
                    {
                        Guid ownerid                    =   ((ADNDynSystemUser)dynCurUser).systemuserid;
                        DynC.ownerid                    =   ownerid;
                    }
                    DynC.adminCreate();
                    if (RatingTrace.Sw.TraceVerbose)
                        Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]RatingContext CompleteRating Response created activityid: {0}.",DynC.activityid),RatingTrace.Sw.Info);
                }
                if ( RatingAnswerCrmID != Guid.Empty ) // We must have the related item
                {
                    ADNDynRatingAnswer DynA             =   new ADNDynRatingAnswer(Wrapper,RatingAnswerCrmID);
                    if ( DynA.adminRetrieve() )
                    {
                        DynA.name                       =   UserName;
                        DynA.email                      =   EMail;
	                    DynA.phone                      =   Phone;
	                    DynA.address                    =   Address;
                        DynA.city                       =   City;
                        DynA.zip                        =   Zip;
                        DynA.country                    =   Country;
                        DynA.comment                    =   string.Format("IP:{0},{1}",IPAddress,Comments);
                        if ( DynL != null )
                            DynA.leadid                 =   DynL.leadid;
                        else if ( ( dynCurUser != null ) && !( dynCurUser is ADNDynSystemUser ) ) // we have a real user through membership, assign it as customer to the answer
                        {
                            if ( dynCurUser is ADNDynAccount )
                                DynA.accountid          =   ((ADNDynAccount)dynCurUser).accountid;
                            else if ( dynCurUser is ADNDynContact )
                                DynA.contactid          =   ((ADNDynContact)dynCurUser).contactid;
                            else if ( dynCurUser is ADNDynLead )
                                DynA.leadid             =   ((ADNDynLead)dynCurUser).leadid;
                            if (RatingTrace.Sw.TraceVerbose)
                                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]RatingContext CompleteRating RatingAsnwer realted to dynCurUser SchemaName: {0}.",dynCurUser.SchemaName),RatingTrace.Sw.Info);
                        }
                        DynA.adminUpdate();
                        if (RatingTrace.Sw.TraceVerbose)
                            Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]RatingContext CompleteRating RatingAsnwer created ratinganswerid: {0}.",DynA.ratinganswerid),RatingTrace.Sw.Info);
                    }
                }
            }
			catch (Exception ex)
			{
				if (RatingTrace.Sw.TraceError)
                    Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[E]RatingContext CompleteRating ex: {0}", ex),RatingTrace.Sw.Info);
			}

			if (RatingTrace.Sw.TraceVerbose)
                Trace2.WriteLine("[V]RatingContext CompleteRating END.",RatingTrace.Sw.Info);
        }

        public decimal Rate(RadRating RadRating1,bool UserLogged)
        {
			if (RatingTrace.Sw.TraceVerbose)
                Trace2.WriteLine("[V]RatingContext Rate BEG.",RatingTrace.Sw.Info);
            try
            {
                int currentNumberRatings    =   0;
                decimal currentRating       =    CrmRatingDB.GetAverageRating(RatingItemID,ref currentNumberRatings);
                currentNumberRatings++;
                //get the current Rating from the DataTable

                //calculate the average rating after the a product has been rated
                RatedAverageValue           =   Math.Round(( RadRating1.Value + currentRating * ( currentNumberRatings - 1 ) ) / currentNumberRatings,1);
                //commit changes to the DataTable
                string UserName             =   string.Empty;
                Guid UserId                 =   Guid.Empty;
                string EMail                =   string.Empty;
                string Phone                =   string.Empty;
                string Address              =   string.Empty;
                string City                 =   string.Empty;
                string Zip                  =   string.Empty;
                string Country              =   string.Empty;
                string Comments             =   string.Empty;
                string IPAddress            =   Request.UserHostAddress;
                if ( RatingTrace.Sw.TraceVerbose )
                    Trace2.WriteLine(string.Format(CultureInfo.InvariantCulture,"[V]RatingContext Rate CurrentUser.IsAnonymous: {0}.",CurrentUser.IsAnonymous),RatingTrace.Sw.Info);
                if ( !CurrentUser.IsAnonymous )
                {
                    UserName                =   CurrentUser.UserName;
                    UserId                  =   CurrentUser.ProviderUserKey;
                    EMail                   =   CurrentUser.Email;
                    Phone                   =   CurrentUser.BillPhone;
                    Address                 =   string.Format("{0} / {1} / {2}",CurrentUser.BillAddress1,CurrentUser.BillAddress2,CurrentUser.BillAddress3);
                    City                    =   CurrentUser.BillCity;
                    Zip                     =   CurrentUser.BillZip;
                    Country                 =   CurrentUser.BillCountry;
                    Comments                =   CurrentUser.Company;
                }

                RatingAnswerID = CrmRatingDB.AddRatingAnswer(RatingItemID,RadRating1.Value,IPAddress,UserName,UserId,EMail,Phone,Address,City,Zip,Country,Comments);
                if ( RatingTrace.Sw.TraceVerbose )
                    Trace2.WriteLine(string.Format(CultureInfo.InvariantCulture,"[V]RatingContext Rate RatingAnswerID: {0}.",RatingAnswerID),RatingTrace.Sw.Info);
                if ( RatingTrace.Sw.TraceVerbose )
                    Trace2.WriteLine(string.Format(CultureInfo.InvariantCulture,"[V]RatingContext Rate UseCrm: {0}, RatingCrmDetailID: {1}.",UseCrm,RatingCrmDetailID),RatingTrace.Sw.Info);
                if ( UseCrm && ( RatingCrmDetailID != Guid.Empty ) ) // We must have the related item
                {
                    ADNDynRatingAnswer DynA =   new ADNDynRatingAnswer(Wrapper,string.Format("IP:{0}",IPAddress));
                    DynA.ratingdetailid     =   RatingCrmDetailID;
                    DynA.addonniceid        =   RatingAnswerID;
                    DynA.ratingvalue        =   (double)RadRating1.Value;
                    Guid CampaignId         =   Settings[RStr.Campaign].ToGuid();
                    if ( RatingTrace.Sw.TraceVerbose )
                        Trace2.WriteLine(string.Format(CultureInfo.InvariantCulture,"[V]RatingContext Rate CampaignId: {0}.",CampaignId),RatingTrace.Sw.Info);
                    if ( CampaignId != Guid.Empty )
                        DynA.campaignid     =   CampaignId;
                    // if we must force assign to owner, do it
                    // else if current user is a systemuser, assign to him (in windows authentication, answer will be own by connected user)
                    if ( AssignToOwner )
                    {
                        Guid ownerid        =   Settings[RStr.Owner].ToGuid();
                        if ( RatingTrace.Sw.TraceVerbose )
                            Trace2.WriteLine(string.Format(CultureInfo.InvariantCulture,"[V]RatingContext Rate ownerid from Settings: {0}.",ownerid),RatingTrace.Sw.Info);
                        DynA.ownerid = ownerid;
                    }
                    else if ( ( dynCurUser != null ) && ( dynCurUser is ADNDynSystemUser ) )
                    {
                        Guid ownerid        =   ( (ADNDynSystemUser)dynCurUser ).systemuserid;
                        if ( RatingTrace.Sw.TraceVerbose )
                            Trace2.WriteLine(string.Format(CultureInfo.InvariantCulture,"[V]RatingContext Rate ownerid from dynCurUser: {0}.",ownerid),RatingTrace.Sw.Info);
                        DynA.ownerid        =   ownerid;
                    }
                    
                    // We could have not set rights for everybody, so force owner to admin to not loose ratinganswer
                    bool retryWithAdmin             =   false;
                    try
                    {
                        RatingAnswerCrmID   =   DynA.adminCreate();
                    }
                    catch ( CRMWrapperException wex )
                    {
                        if ( ( wex.InnerException != null ) && ( wex.InnerException is SoapException ) )
                        {
                            SoapException sex   =   wex.InnerException as SoapException;
                            if ( sex.Detail.InnerText.IndexOf("0x80040231") > -1 )
                                retryWithAdmin  =   true;
                        }
                    }
                    if ( retryWithAdmin )
                    {
                        if ( RatingTrace.Sw.TraceError )
                            Trace2.WriteLine(string.Format(CultureInfo.InvariantCulture,"[E]RatingContext Rate Error role for user not alowwed to generate rating answers userid: {0}",DynA.ownerid),RatingTrace.Sw.Info);
                        DynA.ownerid        =   Wrapper.adminUserId;
                        RatingAnswerCrmID   =   DynA.adminCreate();
                    }
                    if ( RatingTrace.Sw.TraceVerbose )
                        Trace2.WriteLine(string.Format(CultureInfo.InvariantCulture,"[V]RatingContext Rate RatingAnswerCrmID: {0}.",RatingAnswerCrmID),RatingTrace.Sw.Info);
                    CrmRatingDB.UpdateRatingAnswerCrmID(RatingAnswerID,RatingAnswerCrmID);
                }
                RadRating1.ReadOnly         =   true;
                if ( RatingTrace.Sw.TraceVerbose )
                    Trace2.WriteLine(string.Format(CultureInfo.InvariantCulture,"[V]RatingContext Rate InputComment: {0}.",InputComment),RatingTrace.Sw.Info);
                if ( !InputComment )
                    CompleteRating(RadRating1,UserName,UserId,EMail,Phone,Address,City,Zip,Country,Comments,UserLogged);
            }
            catch ( Exception ex )
            {
                if ( RatingTrace.Sw.TraceError )
                    Trace2.WriteLine(string.Format(CultureInfo.InvariantCulture,"[E]RatingContext Rate ex: {0}",ex),RatingTrace.Sw.Info);
            }

			if (RatingTrace.Sw.TraceVerbose)
                Trace2.WriteLine("[V]RatingContext Rate END.",RatingTrace.Sw.Info);
            return RatedAverageValue;
        }

    }
}
